package cn.imatu.framework.enums;

import cn.imatu.framework.exception.BizException;

import java.util.EnumSet;

/**
 *
 * private final String code;
 * private final String desc;
 * @author shenguangyang
 */
public interface BaseEnum {
    String getCode();
    String getDesc();

   default boolean isDefault() {
        return false;
    }

    default Integer getNumberCode() {
        return Integer.parseInt(getCode());
    }

    static <E extends Enum<E> & BaseEnum> E ofByCode(Integer code, Class<E> clazz) {
        if (code == null) {
            return null;
        }
        EnumSet<E> all = EnumSet.allOf(clazz);

        return all.stream().filter(e -> code.compareTo(Integer.parseInt(e.getCode())) == 0)
            .findFirst().orElse(all.stream().filter(BaseEnum::isDefault).findFirst().orElse(null));
    }

    static <E extends Enum<E> & BaseEnum> E ofByCode(String code, Class<E> clazz) {
        EnumSet<E> all = EnumSet.allOf(clazz);
        return all.stream().filter(e -> e.getCode().equals(code))
            .findFirst().orElse(all.stream().filter(BaseEnum::isDefault).findFirst().orElse(null));
    }

    static <E extends Enum<E> & BaseEnum> E ofThrowByCode(String code, Class<E> clazz) {
        EnumSet<E> all = EnumSet.allOf(clazz);
        return all.stream().filter(e -> e.getCode().equals(code)).findFirst().orElseThrow(() -> new BizException("{} 不存在", code));
    }

    static <E extends Enum<E> & BaseEnum> String getDesc(String code, Class<E> clazz) {
        EnumSet<E> all = EnumSet.allOf(clazz);
        return all.stream().filter(e -> e.getCode().equals(code)).map(BaseEnum::getDesc).findFirst()
            .orElse(all.stream().filter(BaseEnum::isDefault).map(BaseEnum::getDesc).findFirst().orElse(null));
    }

    static <E extends Enum<E> & BaseEnum> String getDesc(Integer code, Class<E> clazz) {
        EnumSet<E> all = EnumSet.allOf(clazz);
        return all.stream().filter(e -> e.getCode().equals(code + "")).map(BaseEnum::getDesc)
            .findFirst().orElse(all.stream().filter(BaseEnum::isDefault).map(BaseEnum::getDesc).findFirst().orElse(null));
    }
}